package com.science.slam.controller;
import com.science.slam.domain.File;
import com.science.slam.domain.User;
import com.science.slam.exception.BusinessException;
import com.science.slam.exception.ErrorCode;
import com.science.slam.request.EditFileMessageRequestBody;
import com.science.slam.response.BasicResponse;
import com.science.slam.service.FileService;
import com.science.slam.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@CrossOrigin(origins = "http://localhost:5173", allowCredentials = "true")
public class FileController {
    @Autowired
    FileService fileService;

    @Autowired
    UserService userService;
    @PostMapping("/file/submit")
    public BasicResponse<String> processData(MultipartFile file, HttpServletRequest request) throws IOException {
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        if (!userService.checkSubmitAuthorization(currentUser))
            throw new BusinessException(ErrorCode.FILE_NUM_BIG);
        String path = fileService.uploadToCloud(file, currentUser);
        return BasicResponse.success(path);
    }

    @GetMapping("/file/get_video_stream")
    public BasicResponse<Object> downloadVideo(@RequestParam("url") String url,
                                               @RequestParam("id") String id,
                                               HttpServletRequest request,
                                               HttpServletResponse response) throws IOException{
        if (id.isEmpty() && url.isEmpty())
            throw new BusinessException(ErrorCode.PARAMS_NULL);
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        if (!fileService.checkDownloadAuthorization(url, currentUser))
            throw new BusinessException(ErrorCode.NO_PERMISSIONS);
        fileService.getVideoByURL(url, response);
        return BasicResponse.success(null);
    }

    @GetMapping("/file/list")
    public BasicResponse<List<File>> getAllFiles(@RequestParam("account") String account, HttpServletRequest request) {
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        List<File> files = fileService.getAllFiles(account);
        return BasicResponse.success(files);
    }

    @DeleteMapping("/file/delete")
    public BasicResponse<Object> deleteFile(@RequestParam("url") String url, HttpServletRequest request) {
        if (url == null || url.isEmpty())
            throw new BusinessException(ErrorCode.PARAMS_NULL);
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        Boolean b1 = fileService.checkDeleteAuthorization(url, currentUser);
        if (!b1)
            throw new BusinessException(ErrorCode.NO_PERMISSIONS);
        Boolean b = fileService.deleteFileByUrl(url);
        if (!b)
            throw new BusinessException(ErrorCode.SERVER_ERROR);
        Boolean b2 = fileService.deleteFromDatabase(url);
        if (!b2)
            throw new BusinessException(ErrorCode.DATABASE_ERROR);
        return BasicResponse.success(null);
    }

    @PatchMapping("/file/edit")
    public BasicResponse<Object> editFileMessage(@RequestBody EditFileMessageRequestBody body,
                                                 HttpServletRequest request) {
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        Boolean b = fileService.checkEditAuthorization(body.getUrl(), currentUser, body.getMessageName());
        if (!b)
            throw new BusinessException(ErrorCode.NO_PERMISSIONS);
        String url = body.getUrl();
        Boolean b1 = fileService.editFileMessage(url, body);
        if (!b1)
            throw new BusinessException(ErrorCode.SERVER_ERROR);
        return BasicResponse.success(null);
    }

    @GetMapping("/file/search/tags")
    public BasicResponse<List<File>> searchFileByTags(@RequestParam String tags, HttpServletRequest request) {
        if (tags == null)
            throw new BusinessException(ErrorCode.PARAMS_NULL);
        String[] split = tags.split(",");
        ArrayList<String> strings = new ArrayList<String>(List.of(split));
        int n = strings.size();
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (strings.get(i).equals("all")) {
                strings.set(i, "");
                ++count;
            }
        }
        if (count == n) {
            List<File> allPublicFiles = fileService.getAllPublicFiles();
            return BasicResponse.success(allPublicFiles);
        }
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        List<File> files = fileService.searchByTags(strings);
        return BasicResponse.success(files);
    }

    @GetMapping("/file/search/id")
    public BasicResponse<File> searchFileByID(@RequestParam String id, HttpServletRequest request) {
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        File file = fileService.searchByID(id);
        if (file != null && file.getPublicType() != 1) {
            throw new BusinessException(ErrorCode.NO_PERMISSIONS);
        } else if (file == null) {
            throw new BusinessException(ErrorCode.FILE_NOT_EXISTS);
        }
        return BasicResponse.success(file);
    }

    @PatchMapping("/file/look")
    public void incrementLookNumber(String fileID, HttpServletRequest request) {
        User currentUser = userService.getCurrentUser(request);
        if (currentUser == null)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        fileService.incrementLookNumber(fileID);
    }
}

